package org.jeecg.modules.cosmetic.handler;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.modules.cosmetic.entity.TSccsProduct;
import org.jeecg.modules.cosmetic.entity.TToxicologicalCsa;
import org.jeecg.modules.cosmetic.entity.TToxicologicalReport;
import org.jeecg.modules.cosmetic.model.dto.SccsProductDTO;
import org.jeecg.modules.cosmetic.model.dto.ToxCsaDTO;
import org.jeecg.modules.cosmetic.model.dto.ToxFileDTO;
import org.jeecg.modules.cosmetic.model.dto.ToxReportChildDTO;
import org.jeecg.modules.cosmetic.model.vo.ToxCsaPickVO;
import org.jeecg.modules.cosmetic.model.vo.ToxCsaVO;
import org.jeecg.modules.cosmetic.model.vo.ToxReportChildVO;
import org.jeecg.modules.cosmetic.service.ITSccsProductService;
import org.jeecg.modules.cosmetic.service.ITToxicologicalCsaService;
import org.jeecg.modules.cosmetic.service.ITToxicologicalReportService;
import org.jeecg.modules.cosmetic.utils.CurrentUserUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;

import cn.hutool.core.io.FileTypeUtil;
import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class ToxicologicalCsaHandler {

    @Resource
    private ITToxicologicalCsaService toxicologicalCsaService;

    @Resource
    private ITToxicologicalReportService toxicologicalReportService;

    @Resource
    private ITSccsProductService sccsProductService;

    private static final String file_png = "png";
    private static final String file_jpg = "jpg";
    private static final String file_pdf = "pdf";

    @Value("${jeecg.path.upload}")
    private String uploadPath;

    @Value("${jeecg.uploadType}")
    private String uploadType;

    /**
     * 上传文件
     * @param file
     * @return
     */
    public Result<?> upload(MultipartFile file) {
        ToxFileDTO dto = new ToxFileDTO();
        try {
            if (getFileType(file) == 1) return Result.error("文件上传只支持 .pdf 和 .png 和 .jpg 的文件格式");
            dto.setName(file.getOriginalFilename());
            dto.setUrl(CommonUtils.upload(file, uploadPath, uploadType));
            return Result.ok(dto);
        } catch (Exception e) {
            return Result.error("图片上传异常");
        }
    }

    /**
     * 判断文件格式
     * @param file
     */
    public int getFileType(MultipartFile file) {
        try {
            String type = FileTypeUtil.getType(file.getInputStream());
            if (StringUtils.isBlank(type)) {
                return 1;
            } else {
                if ((!file_png.equals(type.toLowerCase()) && !file_jpg.equals(type.toLowerCase()) && !file_pdf.equals(type.toLowerCase()))) {
                    return 1;
                };
            }
            return 0;
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    /**
     * 保存或更新CSA模块数据
     * @param list
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @DS("cosmetic-datasource")
    public Result<?> saveOrupdate(List<ToxCsaVO> list) {
        // 参数不能为空
        if (CollectionUtils.isEmpty(list)) return Result.error("保存或更新的数据不能为空！");
        list.forEach(m -> {

            // 模块标识不能为空
            Optional.ofNullable(m.getForm()).orElseThrow(() -> new JeecgBootException("模块标识不能为空,1-CIR；2-SCCS；3-AICIS!"));
           /* Result<?> result = checkForm(m);
            if (ObjectUtils.isNotEmpty(result)) throw new JeecgBootException(result.getMessage());*/

            // 先保存-更新主数据表
            TToxicologicalCsa tToxicologicalCsa = new TToxicologicalCsa();
            BeanUtils.copyProperties(m, tToxicologicalCsa);
            tToxicologicalCsa.setUpdateBy(CurrentUserUtil.authInfo().getName());
            if (ObjectUtils.isEmpty(m.getId())) {
                tToxicologicalCsa.setCreateBy(CurrentUserUtil.authInfo().getName());
                toxicologicalCsaService.save(tToxicologicalCsa);
            } else {
                toxicologicalCsaService.updateById(tToxicologicalCsa);
            }

            // 先删除报告类型的数据，再保存报告类型的数据
            toxicologicalReportService.removeById(toxicologicalReportService.getOne(new LambdaQueryWrapper<TToxicologicalReport>().eq(TToxicologicalReport::getForeignId, tToxicologicalCsa.getId())
                    .eq(TToxicologicalReport::getToxId, tToxicologicalCsa.getToxId()).eq(TToxicologicalReport::getForm, tToxicologicalCsa.getForm())));
            ToxReportChildVO childVO = m.getToxReportChild();
            if (ObjectUtils.isNotEmpty(childVO)) {
                TToxicologicalReport tToxicologicalReport = new TToxicologicalReport();
                BeanUtils.copyProperties(childVO, tToxicologicalReport);
                tToxicologicalReport.setToxId(m.getToxId());
                tToxicologicalReport.setForeignId(tToxicologicalCsa.getId());
                tToxicologicalReport.setForm(m.getForm());
                toxicologicalReportService.save(tToxicologicalReport);
            }

            // 产品类别有数据，处理产品类别
            if (m.getForm() == 2 && CollectionUtils.isNotEmpty(m.getSccsList())) {
                sccsProductService.removeBatchByIds(sccsProductService.list(new LambdaQueryWrapper<TSccsProduct>().eq(TSccsProduct::getCsaId, tToxicologicalCsa.getId())));
                m.getSccsList().forEach(scc -> {
                    TSccsProduct tSccsProduct = new TSccsProduct();
                    BeanUtils.copyProperties(scc, tSccsProduct);
                    tSccsProduct.setCsaId(tToxicologicalCsa.getId());
                    sccsProductService.save(tSccsProduct);
                });
            }
        });
        return Result.ok();
    }

    /**
     * 判断各个模块对应字段
     * @param vo
     * @return
     */
    public Result<?> checkForm(ToxCsaVO vo) {
        switch (vo.getForm()) {
            case 1:
                if (StringUtils.isNotBlank(vo.getValue())) return Result.error("CIR模块无浓度数值字段");
                if (StringUtils.isNotBlank(vo.getConclude())) return Result.error("CIR模块无结论字段");
                if (CollectionUtils.isNotEmpty(vo.getSccsList())) return Result.error("CIR模块无产品类别字段");
                break;
            case 2:
                if (StringUtils.isNotBlank(vo.getReside())) return Result.error("SCCS模块无驻留字段");
                if (StringUtils.isNotBlank(vo.getRinse())) return Result.error("SCCS模块无淋洗字段");
                if (StringUtils.isNotBlank(vo.getFileName())) return Result.error("SCCS模块无附件名称字段");
                if (StringUtils.isNotBlank(vo.getFileUrl())) return Result.error("SCCS模块无附件地址字段");
                if (StringUtils.isNotBlank(vo.getValue())) return Result.error("SCCS模块无浓度数值字段");
                break;
            case 3:
                if (StringUtils.isNotBlank(vo.getReside())) return Result.error("AICIS模块无驻留字段");
                if (StringUtils.isNotBlank(vo.getRinse())) return Result.error("AICIS模块无淋洗字段");
                if (StringUtils.isNotBlank(vo.getFileName())) return Result.error("AICIS模块无附件名称字段");
                if (StringUtils.isNotBlank(vo.getFileUrl())) return Result.error("AICIS模块无附件地址字段");
                if (StringUtils.isNotBlank(vo.getValue())) return Result.error("AICIS模块无浓度数值字段");
                if (CollectionUtils.isNotEmpty(vo.getSccsList())) return Result.error("AICIS模块无产品类别字段");
                break;
        }
        return null;
    }

    /**
     * 查询CSA模块的数据
     * @param id
     * @param form
     * @return
     */
    public List<ToxCsaDTO> getCSA(Long id, Integer form) {
        // 先查主表数据
        List<TToxicologicalCsa> csaList;
        if (ObjectUtils.isEmpty(form)) {
            csaList = toxicologicalCsaService.list(new LambdaQueryWrapper<TToxicologicalCsa>().eq(TToxicologicalCsa::getToxId, id));
        } else {
            csaList = toxicologicalCsaService.list(new LambdaQueryWrapper<TToxicologicalCsa>().eq(TToxicologicalCsa::getToxId, id).eq(TToxicologicalCsa::getForm, form));
        }

        // 封装返回的数据集
        List<ToxCsaDTO> list = Lists.newArrayList();
        return csaList.stream().map(m -> {
            ToxCsaDTO dto = new ToxCsaDTO();
            BeanUtils.copyProperties(m, dto);

            // 查询报告数据
            TToxicologicalReport report = toxicologicalReportService.getOne(new LambdaQueryWrapper<TToxicologicalReport>().eq(TToxicologicalReport::getForeignId, m.getId()).eq(TToxicologicalReport::getForm, form).eq(TToxicologicalReport::getToxId, id));
            if (ObjectUtils.isNotEmpty(report)) {
                ToxReportChildDTO reportDTO = new ToxReportChildDTO();
                BeanUtils.copyProperties(report, reportDTO);
                dto.setToxReportChild(reportDTO);
            }

            // 查询产品类别数据
            List<TSccsProduct> productList = sccsProductService.list(new LambdaQueryWrapper<TSccsProduct>().eq(TSccsProduct::getCsaId, m.getId()));
            List<SccsProductDTO> sccsList = Lists.newArrayList();
            productList.stream().map(p -> {
                SccsProductDTO ProductDTO = new SccsProductDTO();
                BeanUtils.copyProperties(p, ProductDTO);
                return ProductDTO;
            }).collect(Collectors.toCollection(() -> sccsList));
            dto.setSccsList(sccsList);
            return dto;
        }).collect(Collectors.toCollection( () -> list));
    }

    /**
     * 查询模块下的优选数据
     * @param id
     * @param form
     * @return
     */
    public Long getCSAPick(Long id, Integer form) {
        TToxicologicalCsa toxicologicalCsa = toxicologicalCsaService.getOne(new LambdaQueryWrapper<TToxicologicalCsa>().eq(TToxicologicalCsa::getToxId, id).eq(TToxicologicalCsa::getForm, form).eq(TToxicologicalCsa::getPick, 0));
        if (ObjectUtils.isEmpty(toxicologicalCsa)) {
            return 0L;
        }
        return toxicologicalCsa.getId();
    }

    /**
     * 更新优选和取消优选
     * @param voList
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @DS("cosmetic-datasource")
    public Result<?> updateCSAPick(List<ToxCsaPickVO> voList) {
        if (CollectionUtils.isEmpty(voList)) return Result.error("参数不能为空！");
        voList.forEach(m -> {
            TToxicologicalCsa toxicologicalCsa = toxicologicalCsaService.getOne(new LambdaQueryWrapper<TToxicologicalCsa>().eq(TToxicologicalCsa::getId, m.getId()));
            toxicologicalCsa.setPick(m.getPick());
            toxicologicalCsaService.updateById(toxicologicalCsa);
        });
        return Result.ok();

    }

    /**
     * 删除CSA模块数据
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    @DS("cosmetic-datasource")
    public boolean delete(Long id) {
        TToxicologicalCsa toxicologicalCsa = toxicologicalCsaService.getById(id);
        Optional.ofNullable(toxicologicalCsa).orElseThrow(() -> new JeecgBootException("模块数据为空！"));
        sccsProductService.removeBatchByIds(sccsProductService.list(new LambdaQueryWrapper<TSccsProduct>().eq(TSccsProduct::getCsaId, id)));
        toxicologicalReportService.removeById(toxicologicalReportService.getOne(new LambdaQueryWrapper<TToxicologicalReport>()
                .eq(TToxicologicalReport::getForeignId, id).eq(TToxicologicalReport::getToxId, toxicologicalCsa.getToxId()).eq(TToxicologicalReport::getForm, toxicologicalCsa.getForm())));
        return toxicologicalCsaService.removeById(toxicologicalCsa);
    }

}
